
.global reset_handler
.global undef_handler
.global svc_handler
.global pretech_handler
.global data_handler
.global irq_handler
.global fiq_handler

.text
.balign 32
vector_start:
    ldr pc, reset_handler_addr
    ldr pc, undef_handler_addr
    ldr pc, svc_handler_addr
    ldr pc, prefetch_handler_addr
    ldr pc, data_handler_addr
    b   .
    ldr pc, irq_handler_addr
    ldr pc, fiq_handler_addr
    reset_handler_addr:     .word reset_handler
    undef_handler_addr:     .word undef_handler
    svc_handler_addr:       .word svc_handler
    prefetch_handler_addr:  .word pretech_handler
    data_handler_addr:      .word data_handler
    irq_handler_addr:       .word irq_handler
    fiq_handler_addr:       .word fiq_handler
vector_done:

.global copy_vector
copy_vector:
    ldr r0, =vector_start
    mcr p15, 0, r0, c12, c0, 0
    mov pc, lr

reset_handler:
    mov r0, #1
    b  other_exception_handle
undef_handler:
    mov r0, #2
    b  other_exception_handle
svc_handler:
    mov r0, #3
    b  other_exception_handle
pretech_handler:
    mov r0, #4
    b  other_exception_handle
data_handler:
    mov r0, #5
    b  other_exception_handle
fiq_handler:
    mov r0, #6
    b  other_exception_handle

irq_handler:
    add     lr, lr, #-4
    push    {r0-r12}
    push    {lr}
    mrc     p15, 4, r0, c15, c0, 0 //periphal base address
    ldr     r1, =#0x10c
    add     r1, r1, r0
    ldr     r0, [r1]                //read ack
    push    {r0-r1} //int id

    mrc     p15, 0, r4, c0, c0, 5
    and     r4, r4, #3
    ldr     r5, =system_state
    add     r5, r5, r4, LSL #2
    ldr     r6, [r5]
    add     r6, #1
    str     r6, [r5]
    bl      do_irq_handle
    add     r6, #-1
    str     r6, [r5]
    pop     {r0-r1}
    str     r0, [r1, #4]    //write ack
    // check re-sched need or not

    mov     r0, r4
    ldr     r1, =need_resched
    add     r1, r1, r0, lsl #2
    ldr     r1, [r1]
    cmp     r1, #0
    beq     direct_return
    bl      schedule_irq_reschedule
    cmp     r0, #1
    beq     save_curr_task_from_irq
    direct_return:
    pop     {lr}
    pop     {r0-r12}
    movs    pc, lr